import { messages } from "share/common";
import React, { Component, PropTypes } from "react";
import { connect } from "react-redux";
import { Tabs, Icon } from "antd";
const TabPane = Tabs.TabPane;
import "styles/financial-management/finance-audit/slide-expense-report-detail/slide-expense-report-detail.scss";
import expenseReportService from "containers/expense-report/expense-report.service";
import baseService from "share/base.service";
import SlideExpenseReportDetailAlert from "./slide-expense-report-detail-alert";
import SlideExpenseReportDetailHeader from "./slide-expense-report-detail-header";
import SlideExpenseReportDetailRelative from "./slide-expense-report-detail-relative";
import SlideExpenseReportDetailExpense from "./slide-expense-report-detail-expense";
import SlideExpenseReportDetailHistory from "./slide-expense-report-detail-history";
import SlideExpenseReportDetailBudget from "./slide-expense-report-detail-budget";
import SlideExpenseReportDetailBar from "./slide-expense-report-detail-bar";
import SlideExpenseReportDetailPay from "./slide-expense-report-detail-pay";
import SlideExpenseReportDetailExpenseInvoice from "./slide-expense-report-detail-expense/slide-expense-report-detail-expense-invoice";
import expenseService from "containers/my-account/expense.service";
import CertificatePreview from "../certificate-preview";
import ConcurrentMark from "../../../expense-report/template/concurrent-mark";
import SlideDocument from "components/template/slide-document/slide-document";
import financeAuditService from "../finance-audit.service";
import SlideFrame from "share/openSlideFrame";
import NewExpenseReport from "../../../expense-report/new-expense-report";
import AuditTipsButton from "../../new-finance-audit/components/audit-tips";
import errorMessage from "share/errorMessage";
import AuditTipsBottomFrame from "../components/audit-tips/bottom-frame";
import ExpenseViewBar from "../../expense-view/expense-view-bar";
import expenseReportFunction from "containers/expense-report/expense-report.function";
import requestService from "../../../request/request.service";
import configureStore from "stores/index";
import { setDocumentaryCompany } from "actions/login";
const { isApproveButtonsShow } = expenseReportFunction;

class SlideExpenseReportDetail extends Component {
  state = {
    loading: true,
    info: {},
    form: {},
    applicant: {},
    creditScore: {},
    jobInfo: {},
    approvalHistory: [],
    approvalChains: [],
    budgetExplainNumber: 0,
    invoiceEnabled: false,
    ocrEnabled: false,
    isAuditInApproveStatus: false,
    prendingAudit: false,
    auditCapability: false,
    templateCodeList: [],
    selectedExpense: [],
    expenseReportInvoices: [],
    failedInvoices: [],
    tableLoading: false,
    isWaitForAudit: false,
    isAuditEditable: false,
    isSupportSingleReject: false,
    activeTab: "expense", //默认tab
    selectedInvoice: [],
    auditFlag: false,
  };

  afterCheckOrAuto = (refreshType) => {
    this.setState({ selectedExpense: [] });
    if (refreshType === "invoiceList") {
      this.invoiceRef.getExpenseList(true);
    } else if (refreshType === "receiptList") {
      this.setState({ selectedInvoice: [] });
      this.receiptRef.getInvoiceList();
    } else {
      this.getInfo(this.props);
    }
  };

  //redux中options默认是登录人的权限，单据审核权限应当取单据申请人的，因此当当前单据申请人不是登录人时，需要刷新权限配置
  componentWillMount() {
    const { user, loginUser, entry, tempUserOID, applicantOID } = this.props;
    const {
      options: { auditBaseConfig = {} },
    } = this.props;
    let loginUserOID =
      entry === "invoice-bag-audit" ? tempUserOID : loginUser.userOID;
    // if(loginUserOID !== (applicantOID || user.userOID)) {
    //   baseService.changeLoginInfo(applicantOID || user.userOID, true).then(res => {
    //     //登录人和单据申请人确实不是一个人，但应用在同一条规则下
    //     if(res[3].data.auditBaseConfig.baseConfigId === auditBaseConfig.baseConfigId) {
    //       this.getInfo(this.props);
    //     }
    //   });
    //   return;
    // }
    this.getInfo(this.props);
  }

  componentWillReceiveProps(nextProps) {
    const {
      expenseReportOID,
      options: { auditBaseConfig: newAuditBaseConfig = {} },
    } = nextProps;
    const {
      options: { auditBaseConfig = {} },
    } = this.props;
    if (expenseReportOID && expenseReportOID !== this.props.expenseReportOID) {
      this.getInfo(nextProps);
    }

    if (auditBaseConfig.baseConfigId !== newAuditBaseConfig.baseConfigId) {
      this.getInfo(nextProps);
    }
  }

  //关闭侧拉框后需更新redux内options为当前登录人的
  componentWillUnmount() {
    const { user, loginUser, entry, tempUserOID, applicantOID } = this.props;
    let loginUserOID =
      entry === "invoice-bag-audit" ? tempUserOID : loginUser.userOID;
    if (loginUserOID !== (applicantOID || user.userOID)) {
      baseService.changeLoginInfo(loginUserOID);
    }
    configureStore.store.dispatch(setDocumentaryCompany({}));
  }

  getInfo = (props = this.props, refreshAll = true) => {
    const { expenseReportOID } = props;
    const { profile, close } = this.props;
    this.setState({ loading: true });
    expenseReportService
      .getExpenseReportDetail(expenseReportOID, { showNodeName: true })
      .then((res) => {
        let expenseDetail = res.data.rows || {};
        if (profile["web.invoice.keep.consistent.with.expense"]) {
          expenseDetail.currencySame = true;
        }
        if (refreshAll) {
          this.getBudgetExplainNumber(expenseDetail.id);
          this.getInvoiceOpenStatus();
          this.getAuditFlag(expenseDetail.expenseReportOID);
        }
        if (expenseDetail.companyOID !== expenseDetail.docCompanyOID) {
          requestService
            .getCompanyDetail(expenseDetail.docCompanyOID)
            .then((res) => {
              configureStore.store.dispatch(setDocumentaryCompany(res.data));
            });
        }
        this.setState(
          {
            info: expenseDetail,
            loading: refreshAll,
            activeTab:
              props.params && props.params.activeTab
                ? props.params.activeTab
                : this.state.activeTab,
          },
          () => refreshAll && this.getThirdInterface(props)
        );
      })
      .catch((err) => {
        console.log(err);
        errorMessage(err.response);
        setTimeout(close, 1000);
      });
  };

  getAuditFlag = (entityOID) => {
    financeAuditService
      .getAuditFlag({ entityOID, entityType: 1002 })
      .then((res) => {
        this.setState({ auditFlag: res.data });
      });
  };

  getThirdInterface = (props) => {
    const { info } = this.state;
    const options = props.options || this.props.options;
    const { auditBaseConfig = {} } = options;
    const { status } = this.props.params;
    const {
      expenseReportOID,
      applicantOID,
      applicantJobId,
      setOfBooksId,
    } = info;
    this.getUserInfo(applicantOID);
    this.getHistory();
    let thirdInterface = [
      expenseReportService.getFormInfo(expenseReportOID),
      applicantJobId && expenseReportService.getJobInfo(applicantJobId),
      expenseReportService.getAuditChain(expenseReportOID, 1002),
      baseService.getHonestInfo(applicantOID, applicantJobId),
      expenseReportService.checkInvoice(expenseReportOID),
      status === "prending_audit" && expenseService.getAccountFlag(),
    ];
    Promise.all(thirdInterface)
      .then((res) => {
        let isAuditInApproveStatus =
          res[2].data.chainDTO &&
          res[2].data.chainDTO.currentFlag &&
          res[2].data.chainDTO.nodeType === 1012;
        let prendingAudit = res[2].data.prendingAudit;
        let isWaitForAudit =
          this.props.entry !== "view" &&
          this.checkNewAuth() &&
          ((info.status === 1003 && prendingAudit) || isAuditInApproveStatus);
        let isAuditEditable =
          isWaitForAudit &&
          auditBaseConfig.reviewEditSuitable &&
          auditBaseConfig.reviewEditEnable;
        let isSupportSingleReject =
          auditBaseConfig.reviewEditSuitable &&
          auditBaseConfig.expenseBatchReject;
        this.setState({
          loading: status === "prending_audit",
          form: res[0].data.rows || {},
          jobInfo: res[1] ? res[1].data || {} : {},
          isAuditInApproveStatus,
          prendingAudit,
          isWaitForAudit,
          isAuditEditable,
          creditScore: res[3].data,
          failedInvoices: res[4].data || [],
          isSupportSingleReject,
        });
        return res[5];
      })
      .then((res) => {
        res &&
          res.data &&
          expenseService
            .getCertificatePreviewTab(setOfBooksId)
            .then((ledgerRes) => {
              let templateCodeList =
                ledgerRes.data && Array.isArray(ledgerRes.data)
                  ? ledgerRes.data
                      .filter(
                        (i) =>
                          (i.templateCode === "GL_EXPENSE" &&
                            i.isEnable === true) ||
                          (i.templateCode === "GL_WRITE_OFF" &&
                            i.isEnable === true)
                      )
                      .map((i) => i.templateCode)
                  : [];
              this.setState({ templateCodeList, loading: false });
            })
            .catch(() => {
              this.setState({ loading: false });
            });
        !(res && res.data) && this.setState({ loading: false });
      })
      .catch((e) => {
        this.setState({ loading: false });
      });
  };

  //获取员工信息
  getUserInfo = (applicantOID) => {
    baseService.getUserInfo(applicantOID).then((res) => {
      this.setState({ applicant: res.data });
    });
  };

  getHistory = () => {
    const {
      info: { expenseReportOID, status },
    } = this.state;
    const { entry, loginUser } = this.props;
    expenseReportService.getExpenseHistoryInfo(expenseReportOID).then((res) => {
      let approvalChains = (res.data.rows || {}).approvalChains || [];
      let isWaitForApprove = isApproveButtonsShow(
        approvalChains,
        loginUser.userOID,
        status
      );
      let auditCapability =
        isWaitForApprove &&
        approvalChains.length > 0 &&
        approvalChains[0].invoiceAllowUpdateType === 1 &&
        entry === "audit" &&
        approvalChains[0].nodeType === 1012;
      this.setState({
        approvalHistory: (res.data.rows || {}).approvalHistoryDTOs || [],
        approvalChains,
        auditCapability,
      });
    });
  };

  //获取预算执行结果数量
  getBudgetExplainNumber = (id) => {
    expenseReportService
      .getBudgetExplainCount({
        documentType: "EXP_REPORT",
        documentId: id,
      })
      .then((res) => {
        this.setState({ budgetExplainNumber: res.data });
      });
  };

  //是否开通发票查验和OCR
  getInvoiceOpenStatus = () => {
    const { loginUser } = this.props;
    expenseService.getTitleList(loginUser.userOID).then((res) => {
      this.setState({
        invoiceEnabled: res.data.showCheckInvoiceFlag,
        ocrEnabled: res.data.showOCRFlag,
      });
    });
  };

  onGetInvoice = (expenseReportInvoices) => {
    this.setState({ expenseReportInvoices });
  };

  onSelectExpense = (selectedExpense) => {
    this.setState({ selectedExpense });
  };

  getChildContext() {
    const { entry, readOnly } = this.props;
    const {
      applicant,
      jobInfo,
      info,
      form,
      approvalHistory,
      auditCapability,
      ocrEnabled,
      approvalChains,
      invoiceEnabled,
      creditScore,
      isAuditInApproveStatus,
      prendingAudit,
      isWaitForAudit,
      isAuditEditable,
      isSupportSingleReject,
    } = this.state;
    return {
      applicant,
      jobInfo,
      info,
      form,
      approvalHistory,
      auditCapability,
      approvalChains,
      ocrEnabled,
      invoiceEnabled,
      isAuditInApproveStatus,
      isWaitForAudit,
      creditScore,
      prendingAudit,
      isAuditEditable,
      isSupportSingleReject,
      entityType: 1002,
      entry,
      readOnly: ["invoice-bag-audit", "audit"].includes(entry)
        ? !isWaitForAudit
        : readOnly,
    };
  }

  onClickCollapse = () => {
    const { tableRefMap } = this.state;
    this.setState({ tableLoading: true }, () => {
      setTimeout(() => {
        tableRefMap &&
          tableRefMap.length &&
          tableRefMap.map((i) => {
            const { tableRef, columns } = i;
            tableRef.refreshTableColumnsWidth(columns);
          });
        this.setState({ tableLoading: false });
      }, 301);
    });
  };

  onClickEditFields = () => {
    const { info, form, jobInfo, isAuditEditable } = this.state;
    SlideFrame.openSlideFrame(
      {
        title: messages("expense-14.key299") /*编辑报销单*/,
        content: NewExpenseReport,
        params: {
          isAuditEditable,
          expenseReport: info,
          formDetail: form,
          jobInfo,
          applicantJobId: info.applicantJobId,
        },
        hasFooter: false,
        afterClose: (params) =>
          params && params.refresh && this.getInfo(info, false),
      },
      this
    );
  };

  annotateService = () => {
    const { info } = this.state;
    return financeAuditService.getAnnotateByEntityOID(
      info.expenseReportOID,
      "DOCUMENT"
    );
  };

  renderTabBarExtra = () => {
    const { language, params, entry } = this.props;
    const { auditFlag, approvalChains, isAuditInApproveStatus } = this.state;
    const auditAlert = (
      <div className="slide-expense-report-detail-right-audit-ing">
        <Icon type="clock-circle" />{" "}
        {messages("expense-14.key300") /*自动审核中请等待*/}
      </div>
    );
    {
      /*多级审核审核并发标记 || 审批流审批并发标记*/
    }
    const concurrentMark = (
      <ConcurrentMark
        entityOID={params.expenseReportOID}
        approvalChains={approvalChains}
        isAuditInApproveStatus={isAuditInApproveStatus}
        style={{ marginRight: language.code === "zh_cn" ? 40 : 0 }}
      />
    );
    const auditTipVisible = language.code === "zh_cn" && entry !== "view";
    const auditTip = <AuditTipsButton from="auditDetail" />;
    let extraDom = null;
    if (auditFlag && auditTipVisible) {
      extraDom = (
        <div className="has-audit-tip">
          {auditAlert} {auditTip}
        </div>
      );
    } else if (auditFlag) {
      extraDom = auditAlert;
    } else if (auditTipVisible) {
      extraDom = auditTip;
    }
    return (
      <div>
        {concurrentMark} {extraDom}
      </div>
    );
  };

  renderBar = () => {
    const {
      info,
      selectedExpense,
      failedInvoices,
      expenseReportInvoices,
      selectedInvoice,
    } = this.state;
    if (this.props.entry === "view") {
      return <ExpenseViewBar info={info} goBack={this.props.close} />;
    }
    return (
      <SlideExpenseReportDetailBar
        selectedExpense={selectedExpense}
        selectedInvoice={selectedInvoice}
        expenseReportInvoices={expenseReportInvoices}
        goBack={this.props.close}
        failedInvoices={failedInvoices}
        afterCheckOrAuto={this.afterCheckOrAuto}
        onSelectExpense={this.onSelectExpense}
      />
    );
  };

  render() {
    const {
      loading,
      info,
      budgetExplainNumber,
      templateCodeList,
      selectedExpense,
      expenseReportInvoices,
      tableLoading,
      ocrEnabled,
      isWaitForAudit,
      isAuditEditable,
      activeTab,
      selectedInvoice,
    } = this.state;
    const { close, company, loginUser, language, entry } = this.props;
    return (
      <SlideDocument
        loading={loading}
        className="slide-expense-report-detail"
        onClickCollapse={this.onClickCollapse}
        fieldsParams={{
          annotateService: this.annotateService,
          annotateDisabled: !isWaitForAudit,
          showEdit: isAuditEditable,
          showBookDate: entry === "audit" || entry === "invoice-bag-audit",
          onClickEdit: this.onClickEditFields,
          company: company,
          user: loginUser,
          refreshInfo: this.getInfo,
        }}
        left={
          <div>
            <SlideExpenseReportDetailAlert />
            <SlideExpenseReportDetailHeader />
          </div>
        }
        right={
          <div className="slide-expense-report-detail-right">
            <Tabs
              activeKey={activeTab}
              tabBarExtraContent={this.renderTabBarExtra()}
              className="right-tabs"
              onChange={(activeTab) =>
                this.setState({
                  activeTab,
                  selectedExpense: [],
                  selectedInvoice: [],
                })
              }
            >
              <TabPane
                tab={messages("expense-14.key301") /*费用明细*/}
                key="expense"
              >
                <SlideExpenseReportDetailExpense
                  ref={(ref) => (this.invoiceRef = ref)}
                  selectedExpense={selectedExpense}
                  activeTab={activeTab}
                  onSelectExpense={this.onSelectExpense}
                  onGetInvoice={this.onGetInvoice}
                  onClickCollapse={(tableRefMap) =>
                    this.setState({ tableRefMap })
                  }
                  tableLoading={tableLoading}
                  afterSave={this.getInfo}
                  goBack={close}
                />
              </TabPane>

              <TabPane
                tab={messages("expense-14.key302") /*发票模式*/}
                key="invoice"
              >
                <SlideExpenseReportDetailExpenseInvoice
                  ref={(ref) => (this.receiptRef = ref)}
                  selectedInvoice={selectedInvoice}
                  showOCRFlag={ocrEnabled}
                  expenseReportInvoices={expenseReportInvoices}
                  onSelectInvoice={(selectedInvoice) =>
                    this.setState({ selectedInvoice })
                  }
                  refreshInfo={this.getInfo}
                  goBack={close}
                />
              </TabPane>

              {budgetExplainNumber > 0 && (
                <TabPane
                  tab={messages("expense-14.key303") /*预算执行*/}
                  key="budget"
                >
                  <SlideExpenseReportDetailBudget />
                </TabPane>
              )}
              {templateCodeList.length && (
                <TabPane
                  tab={messages("expense-14.key304") /*凭证预览*/}
                  key="preview"
                >
                  <CertificatePreview
                    templateCodeList={templateCodeList}
                    bookDate={info.bookDate}
                    bookDateType={info.bookDateType}
                    params={{
                      businessCode: info.businessCode,
                      entityType: 1002,
                      setOfBooksId: info.setOfBooksId,
                      operatorOid: loginUser.userOID,
                      forceRefresh: false,
                    }}
                  />
                </TabPane>
              )}
              <TabPane
                tab={messages("expense-14.key305") /*收款信息*/}
                key="pay"
              >
                <SlideExpenseReportDetailPay afterWriteOff={this.getInfo} />
              </TabPane>
              <TabPane
                tab={messages("expense-14.key306") /*审批历史*/}
                key="history"
              >
                <SlideExpenseReportDetailHistory />
              </TabPane>
            </Tabs>
          </div>
        }
        bar={this.renderBar()}
        tipsFrame={
          language.code === "zh_cn" && this.props.entry !== "view" ? (
            <AuditTipsBottomFrame
              from="auditDetail"
              style={{ bottom: 62, zIndex: 10 }}
            />
          ) : null
        }
      />
    );
  }

  static propTypes = {
    expenseReportOID: PropTypes.string,
  };

  static childContextTypes = {
    applicant: PropTypes.object,
    jobInfo: PropTypes.object,
    info: PropTypes.object,
    form: PropTypes.object,
    approvalHistory: PropTypes.array,
    auditCapability: PropTypes.bool,
    approvalChains: PropTypes.array,
    ocrEnabled: PropTypes.bool,
    invoiceEnabled: PropTypes.bool,
    isAuditInApproveStatus: PropTypes.bool,
    isWaitForAudit: PropTypes.bool,
    creditScore: PropTypes.object,
    prendingAudit: PropTypes.bool,
    isAuditEditable: PropTypes.bool,
    isSupportSingleReject: PropTypes.bool,
    entityType: PropTypes.number,
    entry: PropTypes.string,
    readOnly: PropTypes.bool,
  };
}

let mapStateToProps = (state) => {
  return {
    profile: state.login.profile,
    company: state.login.company,
    user: state.login.user,
    loginUser: state.login.loginUser,
    options: state.login.options,
    language: state.main.language,
  };
};

export default connect(mapStateToProps)(SlideExpenseReportDetail);
